#ifndef MANAGER_H
#define MANAGER_H

#include <list>
#include <string>
#include <vector>

#include "defines.h"

class Monster;
class MapObject;
class Tile;
class Item;

class Manager
{
public:
	Manager();
	~Manager(); // maybe later, when we implement saves.
	void start();
	inline void doDraw() { draw( 0 ); };
	int mapaddch( int y, int x, int symbol );
	bool wait();
	bool resume();
// map related
	void loadMap( int mapIndex );
	void loadMap( map * );
	void readLoadMap( const char * mapFile );
	map * generateMap();
	map * readMap( const char * mapFile );
	std::list< MapObject * > & getMObjs();
	Tile * ( &getMTiles() ) [ MAP_X ][ MAP_Y ];
	std::list< Item * > & getMItems();
	std::list< Monster * > & getMMrs();
// events handlers
	void addFlyMonster( Monster *, int force, int direction );
	void flyMonsters();
// interface
	void openHelp();
	void openInventory();
	// should implement these two below as MapObjects' methods
	void addVisMsg( const std::string &, MapObject * );
	void addVisMsg( const char *, MapObject * );
	void addMsg( const std::string & );
	void addMsg( const char * );
	void attackMsg( Monster *, Monster *, int );
	void dropMsg( Monster *, Item * );
	void pickMsg( Monster *, Item * );
	void dieMsg( Monster * );
	template< typename T >
	T * listOptions( std::list< T * > options, const char * message );
	template< typename T >
	T * listOptions( std::vector< T * > options, const char * message );
// helpers
	inline Monster * getPlayer();


	MapObject * controlledObject;
private:
	void initializeMap();
	void play(); // main game cycle
	void turn( int key );
	void end();
	void calculateFOV( const MapObject * );
	void calculateShadows( const MapObject * );
	void processMonsters();
	void draw( int fov = 1 );
// interface
	void initInterface();
	void updateInterface();
	void printMessages();
// key functions (to do: name them all appropriately)
	bool keyUp();
	bool keyDown();
	bool keyLeft();
	bool keyRight();
	bool keyNW();
	bool keyNE();
	bool keySE();
	bool keySW();
	bool keyA();
	bool keyD();
	bool keyF();
	bool keyG();
	bool keyI();
	bool playerPickUp();
	bool playerDrop();
	bool keyS();
	bool keyCTRL_D();
	bool playerShoot();
	bool startCursor();
	void cursorShowDesc( MapObject * cursor );
// debug keys
	bool keyA_DEBUG();
	bool keyD_DEBUG();
	bool keyG_DEBUG();
	bool keyM_DEBUG();
	bool keyS_DEBUG();
	void listMapObjects();
	void testMessages();
	void showWeaponTypes();
	void spawnItem();

	
	Monster * player; // player-controlled monster
	std::list< std::string * > messages;
	int recentMsgs;
	WINDOW * mapscr;
	WINDOW * msgscr;
	WINDOW * statscr;
	std::list< flyEvent > flyingMonsters;
	std::list< map * > maps;
	map * curMap;
	bool debug;
	bool waiting;
	bool started; // only one copy at once
};

Monster * Manager::getPlayer()
{
	return player;
}

#endif